﻿#include "FITKAbaqusAdaptorMaterialExpansion.h"
#include "InpKeyLineSpliter.h"

#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterial.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialExpansion.h"

namespace IO
{
    QString FITKAbaqusAdaptorMaterialExpansion::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorMaterialExpansion";
    }

    bool FITKAbaqusAdaptorMaterialExpansion::adaptR()
    {
        
        _materialData = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if (!_materialData || !_reader) return false;

        //回退一行 处理关键字信息 校验
        _reader->backLine();
        bool readOK = false;
        QString line = _reader->readLine();
        InpKeyLineSpliter s(line, _reader);
        if (!line.toLower().startsWith("*expansion")) return false;
        //类型
        Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType materialType = Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion;
        bool create = _materialData->addMaterialBehavior(materialType);
        if (!create) return false;
        auto tempElastic = _materialData->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion);
        if (!tempElastic)return false;
        //获取数据
        Interface::FITKAbaMaterialExpansion* expansion = dynamic_cast<Interface::FITKAbaMaterialExpansion*>(tempElastic);
        if (!expansion)return false;
        //场变量个数
        if (s.hasKey("dependencies"))
        {
            this->_dependencies = s["dependencies"].trimmed().toInt(&readOK);
            if (!readOK)return false;
        }
        //参考温度
        if (s.hasKey("zero"))
        {
            expansion->setReferenceTemperature(s["zero"].trimmed().toDouble(&readOK));
            if (!readOK)return false;
        }
        if (s.hasKey("user"))
        {//是否使用用户子程序

        }
        //获取类型
        QString type = s["type"].trimmed().toUpper();
        if (type.isEmpty() || type == "ISO")
            readOK = this->readTypeIsotroplc();
        else if (type == "ORTHO")
            readOK = this->readTypeOrthotropic();
        else if (type == "ANISO")
            readOK = this->readTypeAnisotropic();
        if (!readOK)
            _materialData->removeMaterialBehavior(materialType);
        return readOK;
    }

    bool FITKAbaqusAdaptorMaterialExpansion::adaptW()
    {
        Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType materialType =
            Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion;
        _materialData = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if (!_materialData || !_writer) return false;
        //获得数据结构
        auto tempElastic = _materialData->getMaterialBehavior(materialType);
        //材料为空则返回
        if (!tempElastic) return true;
        auto expansion = dynamic_cast<Interface::FITKAbaMaterialExpansion*>(tempElastic);
        if (!expansion) return false;
        bool writeOK = false;
        //获取类型
        Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialExpansionType type = expansion->getExpansionType();
        if (type == Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialExpansionType::Isotropic)
            writeOK = this->writeTypeIsotroplc();
        else if (type == Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialExpansionType::Orthotropic)
            writeOK = this->writeTypeOrthotropic();
        else if (type == Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialExpansionType::Anisotropic)
            writeOK = this->writeTypeAnisotropic();
        return writeOK;
    }

    bool FITKAbaqusAdaptorMaterialExpansion::readTypeIsotroplc()
    {
        if (!_materialData)return false;
        //获取数据
        Interface::FITKAbaMaterialExpansion* expansion = dynamic_cast<Interface::FITKAbaMaterialExpansion*>
            (_materialData->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion));
        if (!expansion) return false;
        //设置类型
        expansion->setExpansionType(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialExpansionType::Isotropic);
        //文件应有的一次数据所具有的行数
        int row = (2 + _dependencies) % 8 ? (2 + _dependencies) / 8 + 1 : (2 + _dependencies) / 8;

        QString line;
        bool ok = false;
        int  num = 0;
        int index = 0;
        while (!_reader->atEnd())
        {
            line = _reader->readLine().trimmed();
            if (line.startsWith("*"))break;
            expansion->setIsotropicNumberOfRows(index + 1);
            //移除最后一个,预防干扰
            if (line.endsWith(','))line.chop(1);
            QStringList str;
            if (!line.trimmed().isEmpty())
                str = line.trimmed().split(',');
            for (int j = 0; j < 8 && j < str.size(); ++j)
            {
                ++num;
                if (num == 2)
                    if (str.at(j).trimmed().isEmpty())
                        continue;
                    else
                        expansion->setUseTemperatureDependentData(true);
                //读取数据
                double v = str.at(j).trimmed().toDouble(&ok);
                if (!ok)return false;
                //ExpansionCoeff
                if (num == 1)
                    expansion->setIsoTropicExpansionCoeff(v, index);
                //Temperature
                else if (num == 2)
                    expansion->setIsotropicTemperature(v, index);
            }
            if (num % 8 != 0 || num / 8 == row)
            {
                ++index;
                if (num < 1)return false;
                num = 0;
            }
        }
        return true;
    }

    bool FITKAbaqusAdaptorMaterialExpansion::readTypeOrthotropic()
    {
        if (!_materialData)return false;
        //获取数据
        Interface::FITKAbaMaterialExpansion* expansion = dynamic_cast<Interface::FITKAbaMaterialExpansion*>
            (_materialData->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion));
        if (!expansion) return false;
        //设置类型
        expansion->setExpansionType(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialExpansionType::Orthotropic);
        //文件应有的一次数据所具有的行数
        int row = (4 + _dependencies) % 8 ? (4 + _dependencies) / 8 + 1 : (4 + _dependencies) / 8;

        QString line;
        bool ok = false;
        int  num = 0;
        int index = 0;
        while (!_reader->atEnd())
        {
            line = _reader->readLine().trimmed();
            if (line.startsWith("*"))break;
            expansion->setIsotropicNumberOfRows(index + 1);
            //移除最后一个,预防干扰
            if (line.endsWith(','))line.chop(1);
            QStringList str;
            if (!line.trimmed().isEmpty())
                str = line.trimmed().split(',');
            for (int j = 0; j < 8 && j < str.size(); ++j)
            {
                ++num;
                if (num == 4)
                    if (str.at(j).trimmed().isEmpty())
                        continue;
                    else
                        expansion->setUseTemperatureDependentData(true);
                //读取数据
                double v = str.at(j).trimmed().toDouble(&ok);
                if (!ok)return false;
            }
            if (num % 8 != 0 || num / 8 == row)
            {
                ++index;
                if (num < 3)return false;
                num = 0;
            }
        }
        return true;
    }

    bool FITKAbaqusAdaptorMaterialExpansion::readTypeAnisotropic()
    {
        if (!_materialData)return false;
        //获取数据
        Interface::FITKAbaMaterialExpansion* expansion = dynamic_cast<Interface::FITKAbaMaterialExpansion*>
            (_materialData->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion));
        if (!expansion) return false;
        //设置类型
        expansion->setExpansionType(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialExpansionType::Anisotropic);
        //文件应有的一次数据所具有的行数
        int row = (7 + _dependencies) % 8 ? (7 + _dependencies) / 8 + 1 : (7 + _dependencies) / 8;

        QString line;
        bool ok = false;
        int  num = 0;
        int index = 0;
        while (!_reader->atEnd())
        {
            line = _reader->readLine().trimmed();
            if (line.startsWith("*"))break;
            expansion->setIsotropicNumberOfRows(index + 1);
            //移除最后一个,预防干扰
            if (line.endsWith(','))line.chop(1);
            QStringList str;
            if (!line.trimmed().isEmpty())
                str = line.trimmed().split(',');
            for (int j = 0; j < 8 && j < str.size(); ++j)
            {
                ++num;
                if (num == 7)
                    if (str.at(j).trimmed().isEmpty())
                        continue;
                    else
                        expansion->setUseTemperatureDependentData(true);
                //读取数据
                double v = str.at(j).trimmed().toDouble(&ok);
                if (!ok)return false;
            }
            if (num % 8 != 0 || num / 8 == row)
            {
                ++index;
                if (num < 6)return false;
                num = 0;
            }
        }
        return true;
    }

    bool FITKAbaqusAdaptorMaterialExpansion::writeTypeIsotroplc()
    {
        Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType materialType =
            Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion;
        _materialData = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if (!_materialData || !_writer) return false;
        //获得数据结构
        auto tempElastic = _materialData->getMaterialBehavior(materialType);
        //材料为空则返回
        if (!tempElastic) return true;
        auto expansion = dynamic_cast<Interface::FITKAbaMaterialExpansion*>(tempElastic);
        if (!expansion) return false;
        //获取数据行
        int count = expansion->getIsotropicNumberOfRows();
        if (count < 1) return false;
        //开始写出
        QTextStream* stream = _writer->getStream();
        QString lineOne = "*Expansion";
        if (fabsl(expansion->getReferenceTemperature()) > 1e-16)
            lineOne += QString(", zero=%1").arg(_writer->double2String(expansion->getReferenceTemperature(), 8, 0));
        *stream << lineOne << endl;
        //写出数据
        bool isTemperature = expansion->getUseTemperatureDependentData();
        for (int i = 0; i < count; ++i)
        {
            double coeff = expansion->getIsotropicExpansionCoeff(i);
            double t = expansion->getIsotropicTemperature(i);
            lineOne = QString("%1,").arg(_writer->double2String(coeff, 7, 0));
            if (isTemperature)
                lineOne += QString(" %1").arg(_writer->double2String(t, 7, 0));
            *stream << lineOne << endl;
        }
        return true;
    }

    bool FITKAbaqusAdaptorMaterialExpansion::writeTypeOrthotropic()
    {
        return true;
    }

    bool FITKAbaqusAdaptorMaterialExpansion::writeTypeAnisotropic()
    {
        return true;
    }
}
